/*
 * Copyright 2014 Henrik Baerbak Christensen, Aarhus University
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */ 


package cs.rsa.ts14.india;

import cs.rsa.ts14.framework.*;
import java.util.*;

/** Temporary test stub in my TDD development of the
 * StandardTimesagLineProcessor implementation.
 * 
 * Is absolutely correct and can handle all 
 * test cases. (I hope)
 * 
 * @author Kennet Nielsen
 */

public class IndiaLineTypeClassifierStrategy implements
    LineTypeClassifierStrategy {
  
  String lastError;

	@Override
	public LineType classify(String line) {
		lastError = "Unknown error";
		LineType ret = classifyWithoutNoError( line );
		if( ret != LineType.INVALID_LINE )
			lastError = "No error";
		return ret;
	}

	private LineType classifyWithoutNoError(String line) {
		try
		{
			StringTokenizer st = new StringTokenizer(line," \t");
			int tokenCount = st.countTokens();
			if ( tokenCount == 0 ) 
				return LineType.EMPTY_LINE;
			if ( line.charAt(0) == '#' ) 
				return LineType.COMMENT_LINE;
			if ( line.charAt(0) == ' ' || line.charAt(0) == '\t' ) 
			{
				if( tokenCount == 3 )
				{
					if( Character.isLetter( st.nextToken().codePointAt(0) ) )
					{
						String second = st.nextToken();
						if( second.charAt(0) == '-' || Character.isLetter( second.codePointAt(0) ) )
						{
							double hours = Double.parseDouble( st.nextToken() );
							if( hours >= 0 && hours <= 24 && ((hours * 2 ) == (int)(hours * 2 )) )
								return LineType.WORK_SPECIFICATION;
						}
					}
				}
				return LineType.INVALID_LINE;
			}
			if( tokenCount > 1 )
			{
				String first = st.nextToken();
				String second = st.nextToken();
				switch( second )
				{
					case "=":
					{
						if( tokenCount != 3 )
							return LineType.INVALID_LINE;
						for( char curChar : first.toCharArray() )
						{
							if( !Character.isLetter(curChar) ) 
								return LineType.INVALID_LINE;
						}
						String third = st.nextToken();
						Integer.parseInt( third );
						return LineType.ASSIGNMENT_LINE;
					}
					case "Bi": case "Ca": case "Pu": case "Tr": case "No": case "Ho":
					{
						switch( first )
						{
							case "Mon": case "Tue":	case "Wed":	case "Thu":	case "Fri":	case "Sat":
							{
								return LineType.WEEKDAY_SPECIFICATION;
							}
						}
						// no return INVALID here because even if there are 6 token it fails on one of the other tests
					}
				}
				if( tokenCount == 6 )
				{
					int week = Integer.parseInt( second );
					if( week > 0 && week < 54 )
					{
						if( first.compareTo( "Week" ) == 0)
						{
							if( st.nextToken().compareTo( ":" ) == 0)
							{
								int workDays = Integer.parseInt( st.nextToken() );
								if( workDays >= 0 && workDays <= 5 )
								{
									if( st.nextToken().compareTo( ":" ) == 0)
									{
										int vacationDays = Integer.parseInt( st.nextToken() );
										if( vacationDays >= 0 && vacationDays <= 5 )
										{
											if( workDays + vacationDays <= 5 )
											{
												return LineType.WEEK_SPECIFICATION;
											}
										}
									}
								}
							}
						}
					}
				}
			}
		}
		catch( NumberFormatException exp )
		{
		}
		return LineType.INVALID_LINE;
	}

  @Override
  public String lastError() {
    return lastError;
  }

}
